import {_decorator,} from 'cc';

const {ccclass, property} = _decorator;

@ccclass('Pack')
export class Pack {

    cmdId: number;
    data: Uint8Array;

    constructor(cmdId: number, data: Uint8Array) {
        this.cmdId = cmdId;
        this.data = data;
    }

}

@ccclass('PackCodec')
export class PackCodec {
    /**
     * 将pack编码成二进制数据发送
     */
    static encode(pack: Pack): Uint8Array {
        let newData: Uint8Array = new Uint8Array(4 + pack.data.length);
        this.writeIntLittleEndian(newData, 0, pack.cmdId);

        for (let i = 0; i < pack.data.length; i++) {
            newData[4 + i] = pack.data[i];
        }

        return newData;
    }

    /**
     * 将二进制协议解码成pack
     */
    static decode(data: Uint8Array): Pack {
        let cmdId: number = this.readIntLittleEndian(data, 0);
        let newData: Uint8Array = new Uint8Array(data.length - 4);
        for (let i = 0; i < data.length; i++) {
            newData[i] = data[i + 4];
        }
        return new Pack(cmdId, newData);
    }

    /**
     * 小端序:读int
     */
    static readIntLittleEndian(bytes: Uint8Array, offset: number) {
        return (bytes[offset] & 0xFF) |
            ((bytes[offset + 1] & 0xFF) << 8) |
            ((bytes[offset + 2] & 0xFF) << 16) |
            ((bytes[offset + 3] & 0xFF) << 24);
    }

    /**
     * 小端序:写int
     */
    static writeIntLittleEndian(bytes: Uint8Array, offset: number, value: number) {
        bytes[offset] = (value & 0xFF);
        bytes[offset + 1] = ((value >> 8) & 0xFF);
        bytes[offset + 2] = ((value >> 16) & 0xFF);
        bytes[offset + 3] = ((value >> 24) & 0xFF);
    }
}

